package org.seamon.management.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.seamon.management.mapper.DeptMapper;
import org.seamon.management.pojo.dto.DeptInsertDto;
import org.seamon.management.pojo.dto.DeptUpdateDto;
import org.seamon.management.pojo.entity.Dept;
import org.seamon.management.pojo.vo.DeptTreeVo;
import org.seamon.management.service.DeptService;
import org.seamon.management.util.CacheConstants;
import org.seamon.management.util.enums.ErrorCodeEnum;
import org.seamon.management.util.exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author Simon
 * @description 针对表【sys_dept(机构表)】的数据库操作Service实现
 * @createDate 2025-07-11 00:31:54
 */
@Service
@Slf4j
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept>
        implements DeptService {

    /**
     * 获取部门树
     *
     * @return 部门树
     */
    @Override
    @Cacheable(value = CacheConstants.DEPT_TREE, key = "'listTree'")
    public List<DeptTreeVo> listTree() {
        log.debug("未获取缓存，从数据库查询");
        // 查询所有部门
        List<Dept> deptList = this.list();

        // 转换成Vo
        List<DeptTreeVo> treeVos = deptList.stream()
                .map(dept -> {
                    DeptTreeVo deptTreeVO = new DeptTreeVo();
                    BeanUtils.copyProperties(dept, deptTreeVO);
                    return deptTreeVO;
                })
                .sorted(Comparator.comparingInt(DeptTreeVo::getSort))
                .toList();

        // 构建映射
        Map<Long, DeptTreeVo> map = treeVos.stream()
                .collect(Collectors.toMap(DeptTreeVo::getId, Function.identity()));

        // 构建树结构
        List<DeptTreeVo> rootNodes = new ArrayList<>();

        treeVos.forEach(vo -> {
            DeptTreeVo parent = map.get(vo.getParentId());
            if (parent == null) {
                rootNodes.add(vo);
            } else {
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(vo);
            }
        });

        return rootNodes;
    }

    /**
     * 保存部门
     *
     * @param deptDto 部门
     * @return 是否保存成功
     */
    @Override
    @CacheEvict(cacheNames = {CacheConstants.DEPT_LIST, CacheConstants.DEPT_TREE}, allEntries = true)
    public void save(DeptInsertDto deptDto) {
        log.debug("清除缓存");
        Dept dept = new Dept();
        BeanUtils.copyProperties(deptDto, dept);
        this.save(dept);
    }

    @Override
    @CacheEvict(cacheNames = {CacheConstants.DEPT_LIST, CacheConstants.DEPT_TREE}, allEntries = true)
    public void updateById(DeptUpdateDto deptDto) {
        log.debug("清除缓存");
        Dept dept = getDeptByIdOrThrow(deptDto.getId());
        BeanUtils.copyProperties(deptDto, dept);
        dept.setUpdateTime(LocalDateTime.now());
        this.updateById(dept);
    }

    /**
     * 删除部门
     *
     * @param id 部门ID
     * @return 是否删除成功
     */
    @Override
    @CacheEvict(cacheNames = {CacheConstants.DEPT_LIST, CacheConstants.DEPT_TREE}, key = "#id")
    public void removeById(Long id) {
        log.debug("清除缓存");
        Dept dept = getDeptByIdOrThrow(id);
        this.removeById(dept);
    }

    private Dept getDeptByIdOrThrow(Long id) {
        if (id == null) {
            throw new BusinessException(ErrorCodeEnum.DEPT_ID_REQUIRED);
        }
        Dept dept = this.getById(id);
        if (dept == null) {
            throw new BusinessException(ErrorCodeEnum.DEPT_NOT_EXIST);
        }
        return dept;
    }
}




